﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ubatic.Common.Dto;
using System.Transactions;
using Ubatic.Business.Managers;
using Ubatic.Contracts.Services;
using System.Net.Mail;

namespace Ubatic.Business.Services
{
    public class SecurityService : ISecurityService
    {
        private UserManager userMgr = new UserManager();
        private RoleManager roleMgr = new RoleManager();

        #region [Users]

        public bool AuthenticaUser(string nombreDeUsuario, string password)
        {
            if (string.IsNullOrEmpty(nombreDeUsuario) || string.IsNullOrEmpty(password))
                return false;

            bool validUser = false;

            Usuario userDto = userMgr.GetUser(nombreDeUsuario);

            if (userDto != null && userDto.Password == password)
            {
                if (userDto.Activo.HasValue && userDto.Activo.Value)
                {
                    validUser = true;
                }
                else
                {
                    throw new Exception("Debe activar el usuario a traves del email de confirmacion.");
                }
            }
            else
            {
                throw new Exception("Verifique el email y password.");
            }

            return validUser;
        }

        public Usuario GetUser(int userId)
        {
            Usuario dto = this.userMgr.GetUser(userId);
            //dto.Roles = this.roleMgr.GetRolesByUser(userId);
            return dto;
        }

        public Usuario GetUserByEmail(string email)
        {
            return this.userMgr.GetUserByEmail(email);
        }

        public Usuario GetUser(string userName)
        {
            Usuario dto = this.userMgr.GetUser(userName);
            dto.Roles = this.roleMgr.GetRolesByUser(dto.Id);
            return dto;
        }

        public int CreateIncompleteUser(Usuario usuarioDto)
        {
            int userId = this.userMgr.CreateIncompleteUser(usuarioDto);
            usuarioDto.Id = userId;
            SendMail(usuarioDto);
            return userId;
        }       

        private void SendMail(Usuario usuarioDto)
        {            
            // Now lets create an email message
            StringBuilder emailMessage = new StringBuilder();
            emailMessage.Append("Gracias por crear su cuenta en UBATIC");
            emailMessage.Append("<br />");
            emailMessage.Append("Por favor haga click en el link para activar su cuenta <br />");
            emailMessage.Append(string.Format("<a href='http://{0}/Account/ActivateUser.aspx?Id={1}&Code={2}'>Activate {3} </a>", usuarioDto.HttpContextUrlAuthority, usuarioDto.Id, usuarioDto.GuidMailConfirmacion.ToString(), usuarioDto.Email));
            MailMessage email = new MailMessage();
            email.To.Add(new MailAddress(usuarioDto.Email));
            email.Subject = "Por favor active su cuenta UBATIC";
            email.Body = emailMessage.ToString();
            email.IsBodyHtml = true;

            // Send the email
            SmtpClient client = new SmtpClient();            
            client.Send(email);                      
        }

        public int CreateUser(Usuario userDto, List<long> newRoles)
        {
            using (TransactionScope t = new TransactionScope())
            {
                userDto.Id = this.userMgr.CreateUser(userDto);
                this.userMgr.AddUserToRoles(userDto, newRoles);
                t.Complete();
            }
            return userDto.Id;
        }

        public bool ActiveUser(Usuario usuarioDto)
        {
            return this.userMgr.ActiveUser(usuarioDto);
        }

        public bool UpdateUser(Usuario usuarioDto)
        {
            return this.userMgr.UpdateUser(usuarioDto);
        }

        public bool UpdateUser(Usuario userDto, List<long> newRoles, List<long> deleteRoles)
        {
            bool validUpdate = false;
            using (TransactionScope t = new TransactionScope())
            {
                this.userMgr.AddUserToRoles(userDto, newRoles);
                this.userMgr.RemoveUserFromRoles(userDto, deleteRoles);
                validUpdate = this.userMgr.UpdateUser(userDto);
                t.Complete();
            }
            return validUpdate;
        }

        public bool DeleteUser(long userId)
        {
            bool validDelete = false;
            using (TransactionScope t = new TransactionScope())
            {
                try
                {
                    this.userMgr.RemoveUserFromAllRoles(userId);
                    validDelete = this.userMgr.DeleteUser(userId);
                }
                catch(Exception ex)
                {
                    throw ex;
                    //throw new Exception(ExceptionMessages.Existing_Relationship);
                }
                t.Complete();
            }
            return validDelete;
        }

        public List<Usuario> GetUsers()
        {
            return this.userMgr.GetUsers();
        }

        //public List<UsuarioDto> GetUsers(UserSearchDto searchDto)
        //{
        //    return this.userMgr.GetUsers(searchDto);
        //}

        #endregion

        #region Role Members

        public Role CreateRole(Role roleDto)
        {
            roleDto.Id = this.roleMgr.CreateRole(roleDto);
            return roleDto;
        }

        public Role GetRole(long id)
        {
            return this.roleMgr.GetRole(id);
        }

        public bool UpdateRole(Role roleDto)
        {
            return this.roleMgr.UpdateRole(roleDto);
        }

        public bool DeleteRole(long roleId)
        {
            return this.roleMgr.DeleteRole(roleId);
        }

        public List<Role> GetRoles()
        {
            return this.roleMgr.GetRoles();
        }

        #endregion
    }
}
